package com.nuoniu.sibanyun.service.crm.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.DateUtils;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.SysCompany;
import com.nuoniu.sibanyun.entity.SysUser;
import com.nuoniu.sibanyun.entity.crm.*;
import com.nuoniu.sibanyun.entity.crm.bo.GoodsOrderDetailBo;
import com.nuoniu.sibanyun.mapper.crm.CrmGoodsOrderMapper;
import com.nuoniu.sibanyun.service.ISysCompanyService;
import com.nuoniu.sibanyun.service.ISysUserService;
import com.nuoniu.sibanyun.service.crm.*;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallMinutesService;
import com.nuoniu.sibanyun.service.expenses.IExpensesAccountService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * <p>
 * 商品订单 服务实现类
 * </p>
 *
 * @author baiqiang
 * @since 2020-07-17
 */
@Service
@Log4j2
public class CrmGoodsOrderServiceImpl extends ServiceImpl<CrmGoodsOrderMapper, CrmGoodsOrder> implements ICrmGoodsOrderService {

    @Autowired
    private CrmGoodsOrderMapper orderMapper;
    @Autowired
    private ICrmGoodsService goodsService;
    @Autowired
    private ICrmSecretKeyService secretKeyService;
    @Autowired
    private ISysCompanyService companyService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ICommissionRecordService commissionRecordService;
    @Autowired
    private ICrmUserLevelService userLevelService;
    @Autowired
    private ICrmRetailLevelService levelService;
    @Autowired
    private IExpensesAccountService expensesAccountService;
    @Autowired
    private ICrmGoodsCallSettingService goodsCallSettingService;
    @Autowired
    private ICrmCallMinutesService crmCallMinutesService;


    @Override
    public Page<CrmGoodsOrder> pageOrder(Page pages, CrmGoodsOrder order) {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<CrmGoodsOrder> queryWrapper = new QueryWrapper<>();
        if(order.getOrderType() != null) {
            queryWrapper.eq("order_type", order.getOrderType());
        }
        if(StringUtils.isNotBlank(order.getStartTime())){
            queryWrapper.ge("create_date", order.getStartTime());
        }
        if(StringUtils.isNotBlank(order.getEndTime())){
            queryWrapper.le("create_date", order.getEndTime());
        }
        if(!userInfo.getUserName().equals("system")) {
            queryWrapper.eq("company_id", userInfo.getCompanyId());
        }
        if(StringUtils.isNotBlank(order.getCompanyName())) {
            queryWrapper.like("company_name", order.getCompanyName());
        }
        if(StringUtils.isNotBlank(order.getGoodsName())) {
            queryWrapper.like("goods_name", order.getGoodsName());
        }
        if(StringUtils.isNotBlank(order.getOrderNo())) {
            queryWrapper.like("order_no", order.getOrderNo());
        }
        if(order.getOrderStatus() != null) {
            queryWrapper.eq("order_status", order.getOrderStatus());
        }
        queryWrapper.orderByDesc("create_date");
        return page(pages, queryWrapper);
    }

    @Override
    public String getOrderNo() {
        String no = "00001";
        String orderNo = orderMapper.getOrderNo();
        if(StringUtils.isNotBlank(orderNo)) {
            no = Integer.parseInt(orderNo.substring(orderNo.length() - 5, orderNo.length())) + 1 + "";
            if(no.length() > 5) {
                return null;
            }
            if (no.length() == 1) {
                no = "0000" + no;
            }
            if (no.length() == 2) {
                no = "000" + no;
            }
            if (no.length() == 3) {
                no = "00" + no;
            }
            if (no.length() == 4) {
                no = "0" + no;
            }
        }
        return StringUtils.getRandomNum(4) + DateUtils.formatDate(new Date(), "yyyyMMdd") + no;
    }

    @Override
    public void updateCompanyName(SysCompany company) {
        orderMapper.updateCompanyName(company);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveRenew(CrmGoodsOrder order) {
        UserInfo userInfo = UserThreadLocal.get();
        CrmGoods goods = goodsService.getById(order.getGoodsId());
        CrmSecretKey secretKey = secretKeyService.getById(order.getSecretKeyId());
        if(goods == null) {
            throw new NuoNiuException("商品不存在");
        }
        if(secretKey == null) {
            throw new NuoNiuException("续费的秘钥不存在");
        }

        Integer endMonth = secretKey.getEndDate().getYear() * 12 + secretKey.getEndDate().getMonthValue();
        Integer useMonth = LocalDateTime.now().getYear() * 12 + LocalDateTime.now().getMonthValue();
        Integer month = endMonth - useMonth;
        if(month < 0) {
            month = 0;
        }

        BigDecimal userPrice = goods.getPrice().divide(new BigDecimal(goods.getUsers()), 10, BigDecimal.ROUND_HALF_UP); //每个用户每每年单价
        order.setCompanyId(userInfo.getCompanyId());
        order.setOrderNo(this.getOrderNo());
        order.setCompanyId(userInfo.getCompanyId());
        order.setOrderStatus(1);
        order.setPayType(3);
        order.setCompanyName(userInfo.getCompanyName());
        order.setSalePrice(userPrice.multiply(new BigDecimal(order.getYears())).multiply(new BigDecimal(order.getUsers() + secretKey.getUsers())) //续费年限价钱
                .multiply(new BigDecimal(order.getDiscountRate()).multiply(new BigDecimal(0.01))));

        BigDecimal monthUserPrice = userPrice.divide(new BigDecimal(12.0), 10, BigDecimal.ROUND_HALF_UP); ////每个用户每月单价
        order.setSalePrice(order.getSalePrice().add(new BigDecimal(order.getUsers()).multiply(new BigDecimal(month).multiply(monthUserPrice)))); //续费用户价钱
        this.save(order);
        expensesAccountService.changeFromCrmGoodsOrder(order);
        this.updateOrder(order.getId().toString(),order.getPayType());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveOrder(CrmGoodsOrder order) {
        UserInfo userInfo = UserThreadLocal.get();
        String orderBusinessType = order.getOrderBusinessType();
        if(StringUtils.isBlank(orderBusinessType))throw new NuoNiuException("参数错误");
        switch (orderBusinessType){
            /**购买 通用分钟数*/
            case "GeneralMinutes":
            /**购买 保证金*/
            case "Deposit":
                this.saveOrderForSimple(order);
                return;
        }
        CrmGoods goods = goodsService.getById(order.getGoodsId());
        if(goods == null) {
            throw new NuoNiuException("商品不存在");
        }
        String goodsType = goods.getGoodsType();
        if(StringUtils.isBlank(goodsType)) {
            throw new NuoNiuException("商品类型错误");
        }
        order.setOrderNo(this.getOrderNo());
        order.setOrderStatus(1);
        order.setPayType(3);
        if(null == order.getCompanyId() && null != userInfo){
            order.setCompanyId(userInfo.getCompanyId());
        }
        if(StringUtils.isBlank(order.getCompanyName()) && null != userInfo ){
            order.setCompanyName(userInfo.getCompanyName());
        }
        GoodsOrderDetailBo goodsOrderDetailBo = new GoodsOrderDetailBo();
        BeanUtils.copyProperties(goods,goodsOrderDetailBo);
        switch (goodsType){
            /** 软件 */
            case "software":
                if(order.getUsers() < 5) {
                    throw new NuoNiuException("至少购买5个用户量");
                }
                if(order.getYears() < 1) {
                    throw new NuoNiuException("至少购买1年");
                }
                order.setSalePrice(goods.getPrice().multiply(new BigDecimal(order.getYears())).multiply(new BigDecimal(order.getDiscountRate()).multiply(new BigDecimal(0.01))));
                order.setGoodsDetail(JSON.toJSONString(goodsOrderDetailBo));
                this.save(order);
                this.updateOrder(order.getId().toString(), order.getPayType());
                break;
            /** 话费 */
            case "telCharges":
                CrmGoodsCallSetting crmGoodsCallSetting = goodsCallSettingService.getByGoodsId(goods.getId());
                if(null == crmGoodsCallSetting)throw new NuoNiuException("参数错误");
                goodsOrderDetailBo.setMinutePrice(crmGoodsCallSetting.getMinutePrice());
                goodsOrderDetailBo.setBaseMinutes(crmGoodsCallSetting.getBaseMinutes());
                goodsOrderDetailBo.setIsSetting(crmGoodsCallSetting.getIsSetting());
                order.setGoodsDetail(JSON.toJSONString(goodsOrderDetailBo));
                order.setSalePrice(goods.getPrice());
                this.save(order);
                /** 更新套餐信息(商品订单)*/
                crmCallMinutesService.changeFromGoodsOrder(order);
                break;
        }
        expensesAccountService.changeFromCrmGoodsOrder(order);

    }

    @Override
    public void saveOrderForSimple(CrmGoodsOrder order) {
        UserInfo userInfo = UserThreadLocal.get();
        order.setCompanyId(userInfo.getCompanyId());
        order.setOrderNo(this.getOrderNo());
        order.setOrderStatus(1);
        order.setCompanyId(userInfo.getCompanyId());
        order.setCompanyName(userInfo.getCompanyName());
        this.save(order);
        String orderBusinessType = order.getOrderBusinessType();
        if(StringUtils.isBlank(orderBusinessType))throw new NuoNiuException("参数错误");
        switch (orderBusinessType){
//            /**购买 通用分钟数*/
//            case "GeneralMinutes":
//                crmCallMinutesService.changeFromGoodsOrder(order);
//                break;
//            /**购买 保证金*/
//            case "Deposit":
//                crmCallMinutesService.checkByCompanyId(userInfo.getCompanyId());
//                break;
        }
        expensesAccountService.changeFromCrmGoodsOrder(order);
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateOrder(String orderId, Integer payType) {
        CrmGoodsOrder order = this.getById(orderId);
//        if(order.getOrderStatus() > 0) {
//            log.info("=====此订单已经支付过=====" + "id=" + orderId);
//            return;
//        }

        SysCompany company = companyService.getById(order.getCompanyId());
        //保存密钥
        CrmSecretKey secretKey = null;
        if(order.getSecretKeyId() != null) {
            secretKey = secretKeyService.getById(order.getSecretKeyId());
            if(order.getUsers() != null && order.getUsers() > 0) {
                secretKey.setUsers(secretKey.getUsers() + order.getUsers());
            }
            if(order.getYears() != null && order.getYears() > 0) {
                secretKey.setYears(secretKey.getYears() + order.getYears());
                secretKey.setEndDate(secretKey.getEndDate().plusYears(order.getYears()));
            }
            secretKeyService.updateById(secretKey);
        } else {
            secretKey = new CrmSecretKey();
            secretKey.setSecretKey(secretKeyService.getBySecretKey());
            secretKey.setTimes(1);
            secretKey.setUseTimes(1);
            secretKey.setUsers(order.getUsers());
            secretKey.setYears(order.getYears());
            secretKey.setGoodsId(order.getGoodsId());
            secretKey.setGoodsName(order.getGoodsName());
            secretKey.setUseDate(LocalDateTime.now());
            secretKey.setType(1);
            secretKey.setEndDate(LocalDateTime.now().plusYears(order.getYears()));
            secretKeyService.save(secretKey);
        }

        try{
            rewardShareUser(company, order.getSalePrice(), order);
            //首次购买奖励上级
//                if(company.getSecretKeyId() != null) {
//                    CrmSecretKey key = secretKeyService.getById(company.getSecretKeyId());
//                    if(key != null && key.getType() == 0) {
//                        rewardShareUser(company, order.getSalePrice(), order);
//                    }
//                }else {
//                    rewardShareUser(company, order.getSalePrice(), order);
//                }
        }catch (Exception e) {
            e.printStackTrace();
        }

        //修改订单
        order.setPayType(payType);
        order.setSecretKey(secretKey.getSecretKey());
        order.setSecretKeyId(secretKey.getId().intValue());
        order.setOrderStatus(1);
        order.setPayDate(LocalDateTime.now());
        this.updateById(order);
        //使用密钥
        company.setSecretKey(secretKey.getSecretKey());
        company.setSecretKeyId(secretKey.getId().intValue());
        company.setCompanyUser(secretKey.getUsers());
        companyService.updateById(company);
    }

    /**
     * 奖励上级用户
     * @author 小啊刚
     * @date 2020-07-27
     */
    @Async
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void rewardShareUser(SysCompany company, BigDecimal buyerPayAmount, CrmGoodsOrder order) {
        CrmGoods goods = goodsService.getById(order.getGoodsId());
        if(company.getShareUserId() != null && goods.getFirstReward() != null && goods.getFirstReward() > 0 && goods.getIsReward()) {
            String orderNo = order.getOrderNo();
            SysUser firstUser = userService.getById(company.getShareUserId());
            if(firstUser != null) { //奖励第一级
                Integer month = Integer.valueOf(DateUtils.getMonth());
                Integer year = Integer.valueOf(DateUtils.getYear());
                //获取上个月推客奖励系数
                CrmUserLevel upUserLevel = null;
                if(month == 1) {
                    upUserLevel = userLevelService.getByUserId(company.getShareUserId(), year - 1, 12);
                } else {
                    upUserLevel = userLevelService.getByUserId(company.getShareUserId(), year, month - 1);
                }

                CrmRetailLevel level = levelService.getById(1);
                Double rate = upUserLevel != null ? upUserLevel.getDirectCommission() : level.getDirectCommission();
                BigDecimal firstReward = buyerPayAmount.multiply(new BigDecimal(goods.getFirstReward()).multiply(new BigDecimal(0.01)));
                firstUser.setTotalCommission(firstUser.getTotalCommission().add(firstReward.multiply(new BigDecimal(rate))));
                userService.updateById(firstUser);
                //修改推客等级
                CrmUserLevel userLevel = userLevelService.getByUserId(company.getShareUserId(), year, month);
                if(userLevel == null) {
                    userLevel = new CrmUserLevel();
                    userLevel.setMonth(month);
                    userLevel.setYear(year);
                    userLevel.setUserId(company.getShareUserId());
                    userLevel.setName(level.getName());
                    userLevel.setDirectCommission(level.getDirectCommission());
                }
                userLevel.setOrderCount(userLevel.getOrderCount() + 1);
                userLevel.setOrderAmount(userLevel.getOrderAmount().add(order.getSalePrice()));
                userLevel.setSettlementCommission(firstReward.add(userLevel.getSettlementCommission()));
                userLevelService.saveLevel(userLevel);
                //保存第一级奖励记录
                saveCommissionRecord(company.getCompanyName(), orderNo, buyerPayAmount, goods.getFirstReward(), 1, firstReward.multiply(new BigDecimal(rate)), firstUser, upUserLevel != null ? upUserLevel.getName() : level.getName(),  upUserLevel != null ? upUserLevel.getDirectCommission() : level.getDirectCommission());
                if(firstUser.getShareUserId() != null && goods.getSecondReward() != null && goods.getSecondReward() > 0) { //奖励第二级
                    SysUser secondUser = userService.getById(firstUser.getShareUserId());
                    BigDecimal secondReward = buyerPayAmount.multiply(new BigDecimal(goods.getSecondReward()).multiply(new BigDecimal(0.01)));
                    secondUser.setTotalCommission(secondUser.getTotalCommission().add(secondReward));
                    userService.updateById(secondUser);
                    //保存第二级奖励记录
                    saveCommissionRecord(company.getCompanyName(), orderNo, buyerPayAmount, goods.getSecondReward(), 2, secondReward, secondUser, "", 1.0);
                    if(secondUser.getShareUserId() != null && goods.getThirdReward() != null && goods.getThirdReward() > 0) { //奖励第三级
                        SysUser thirdUser = userService.getById(secondUser.getShareUserId());
                        BigDecimal thirdReward = buyerPayAmount.multiply(new BigDecimal(goods.getThirdReward()).multiply(new BigDecimal(0.01)));
                        thirdUser.setTotalCommission(thirdUser.getTotalCommission().add(thirdReward));
                        userService.updateById(thirdUser);
                        //保存第三级奖励记录
                        saveCommissionRecord(company.getCompanyName(), orderNo, buyerPayAmount, goods.getThirdReward(), 3, thirdReward, thirdUser, "", 1.0);
                        if(thirdUser.getShareUserId() != null && goods.getFourthReward() != null && goods.getFourthReward() > 0) { //奖励第四级
                            SysUser fourthUser = userService.getById(thirdUser.getShareUserId());
                            BigDecimal fourthReward = buyerPayAmount.multiply(new BigDecimal(goods.getFourthReward()).multiply(new BigDecimal(0.01)));
                            fourthUser.setTotalCommission(fourthUser.getTotalCommission().add(fourthReward));
                            userService.updateById(fourthUser);
                            //保存第四级奖励记录
                            saveCommissionRecord(company.getCompanyName(), orderNo, buyerPayAmount, goods.getFourthReward(), 4, fourthReward, fourthUser, "", 1.0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 保存佣金记录
     * @author 小啊刚
     * @date 2020-07-28
     */
    public void saveCommissionRecord(String companyName, String orderNo, BigDecimal buyerPayAmount, Integer rewardRate, Integer level, BigDecimal income, SysUser user, String levelName, Double directCommission) {
        CommissionRecord record =  new CommissionRecord();
        record.setOrderNo(orderNo);
        record.setUserId(user.getId().intValue());
        record.setUserName(user.getRealName());
        record.setPayAmount(buyerPayAmount);
        record.setRewardRate(rewardRate);
        record.setRewardLevel(level);
        record.setCompanyName(companyName);
        record.setRewardIncome(income);
        record.setTotalIncome(user.getTotalCommission());
        record.setBalance(user.getTotalCommission().subtract(user.getWithdrawalCommission()));
        record.setRetailLevelName(levelName);
        record.setRetailRate(directCommission);
        commissionRecordService.save(record);
    }
}
